package com.genghis.rapidcrm.web.view;

import com.genghis.rapidcrm.PerformancePrefs;
import com.genghis.rapidcrm.kernel.*;
import com.genghis.rapidcrm.kernel.customview.CustomView;
import com.genghis.rapidcrm.kernel.customview.CustomViewRecordModel;
import com.genghis.rapidcrm.kernel.module.RapidModuleModel;
import com.genghis.rapidcrm.web.view.model.RapidJsScriptModel;
import edu.jetwinner.common.EasyStringUtil;
import edu.jetwinner.common.FastHashMap;
import edu.jetwinner.common.ValueParser;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RapidListView extends RapidIndexView {

    protected String viewName;

    @Override
    public void preProcess(HttpServletRequest request, HttpServletResponse response, boolean display) throws Exception {
        super.preProcess(request, response, false);

        RapidViewer viewer = this.getViewer(request);
        String moduleName = getModule(request);

        RapidListViewModel listViewModel = getAppContextBean(RapidListViewModelProvider.class).getInstance(moduleName);
        Map<String, Object> linkParams = FastHashMap.build(2).add("MODULE", moduleName)
                .add("ACTION", request.getParameter("view")).toMap();
        viewer.assign("CUSTOM_VIEWS", CustomViewRecordModel.getAllByGroup(moduleName));
        this.viewName = request.getParameter("viewname");
        if (EasyStringUtil.isBlank(this.viewName)) {
            //If not view name exits then get it from custom view
            //This can return default view id or view id present in session
            CustomView customView = new CustomView();
            this.viewName = customView.getViewId(moduleName);
        }

        RapidModuleModel moduleModel = getModuleModelInstance(moduleName);
        viewer.assign("MODULE_MODEL", moduleModel);

        viewer.assign("QUICK_LINKS", listViewModel.getSideBarLinks(linkParams));
        this.initializeListViewContents(request, viewer);
        viewer.assign("VIEWID", this.viewName);

        if (display) {
            this.preProcessDisplay(request, response);
        }
    }

    @Override
    protected String preProcessTplName(HttpServletRequest request) {
        return "ListViewPreProcess.tpl";
    }

    //Note : To get the right hook for immediate parent in PHP,
    // specially in case of deep hierarchy
	/*function preProcessParentTplName(HttpServletRequest request) {
		return parent::preProcessTplName($request);
	}*/

    @Override
    protected void preProcessDisplay(HttpServletRequest request, HttpServletResponse response) throws Exception {
        super.preProcessDisplay(request, response);
    }


    @Override
    public void process(HttpServletRequest request, HttpServletResponse response) throws Exception {
        RapidViewer viewer = this.getViewer(request);
        String moduleName = getModule(request);
        this.viewName = request.getParameter("viewname");

        this.initializeListViewContents(request, viewer);
        viewer.assign("VIEW", request.getParameter("view"));
        viewer.assign("CURRENT_USER_MODEL", UsersRecordModel.getCurrentUserModel(request));
        viewer.view("ListViewContents.tpl", moduleName, request, response);
    }

    @Override
    public void postProcess(HttpServletRequest request, HttpServletResponse response) throws Exception {
        RapidViewer viewer = this.getViewer(request);
        String moduleName = getModule(request);

        viewer.view("ListViewPostProcess.tpl", moduleName, request, response);
        super.postProcess(request, response);
    }

    /**
     * Function to get the list of Script models to be included
     *
     * @param request HttpServletRequest
     * @return <Array> - List of Vtiger_JsScript_Model instances
     */
    @Override
    protected List<RapidJsScriptModel> getHeaderScripts(HttpServletRequest request) {
        List<RapidJsScriptModel> headerScriptInstances = super.getHeaderScripts(request);
        String moduleName = getModule(request);

        String[] jsFileNames = {
                "modules.Vtiger.resources.List",
                String.format("modules.%s.resources.List", moduleName),
                "modules.CustomView.resources.CustomView",
                String.format("modules.%s.resources.CustomView", moduleName),
                "modules.Emails.resources.MassEdit",
                "modules.Vtiger.resources.CkEditor"
        };

        Map<String, RapidJsScriptModel> jsScriptInstances = this.checkAndConvertJsScripts(jsFileNames);
        headerScriptInstances.addAll(jsScriptInstances.values());
        return headerScriptInstances;
    }

    /*
     * Function to initialize the required data in smarty to display the List View Contents
     */
    public void initializeListViewContents(HttpServletRequest request, RapidViewer viewer) {
        String moduleName = getModule(request);
        String cvId = this.viewName;
        String pageNumber = request.getParameter("page");
        String orderBy = request.getParameter("orderby");

        String nextSortOrder = "ASC";
        String sortImage = "icon-chevron-up";
        String sortOrder = request.getParameter("sortorder");
        if ("ASC".equals(sortOrder)) {
            nextSortOrder = "DESC";
            sortImage = "icon-chevron-down";
        }

        if (EasyStringUtil.isBlank(pageNumber)) {
            pageNumber = "1";
        }

        RapidListViewModel listViewModel = getAppContextBean(RapidListViewModelProvider.class).getInstance(moduleName, cvId);
        UsersRecordModel currentUser = UsersRecordModel.getCurrentUserModel(request);

        Map<String, Object> linkParams = FastHashMap.build(2).add("MODULE", moduleName)
                .add("ACTION", request.getParameter("view")).add("CVID", cvId).toMap();
        Map<String, List<RapidLinkModel>> linkModels = listViewModel.getListViewMassActions(linkParams);

        RapidPagingModel pagingModel = new RapidPagingModel();
        pagingModel.setPage(ValueParser.parseInt(pageNumber));
        pagingModel.setViewId(request.getParameter("viewname"));

        if (EasyStringUtil.isNotBlank(orderBy)) {
            listViewModel.set("orderby", orderBy);
            listViewModel.set("sortorder", sortOrder);
        }

        String searchKey = request.getParameter("search_key");
        String searchValue = request.getParameter("search_value");
        String operator = request.getParameter("operator");
        if (EasyStringUtil.isNotBlank(operator)) {
            listViewModel.set("operator", operator);
            viewer.assign("OPERATOR", operator);
            viewer.assign("ALPHABET_VALUE", searchValue);
        }
        if (EasyStringUtil.isNotBlank(searchKey) && EasyStringUtil.isNotBlank(searchValue)) {
            listViewModel.set("search_key", searchKey);
            listViewModel.set("search_value", searchValue);
        }

        String[] searchParmams = request.getParameterValues("search_params");
        if (searchParmams == null) {
            searchParmams = new String[0];
        }
//        transformedSearchParams = this.transferListSearchParamsToFilterCondition(searchParmams, listViewModel.getModule());

//        listViewModel.set("search_params", transformedSearchParams);

        //To make smarty to get the details easily accesible
//        foreach($searchParmams as $){
//            foreach($fieldListGroup as $fieldSearchInfo){
//                $fieldSearchInfo["searchValue"] = $fieldSearchInfo[2];
//                $fieldSearchInfo["fieldName"] = $fieldName = $fieldSearchInfo[0];
//                $searchParmams[$fieldName] = $fieldSearchInfo;
//            }
//        }


        Map<String, ?> listViewHeaders = listViewModel.getListViewHeaders();
        List listViewEntries = listViewModel.getListViewEntries(pagingModel);
        int noOfEntries = listViewEntries.size();

        viewer.assign("MODULE", moduleName);

        Map<String, List<RapidLinkModel>> listViewLinks = listViewModel.getListViewLinks(linkParams,
                UsersRecordModel.getCurrentUserModel(request));
        viewer.assign("LISTVIEW_LINKS", listViewLinks);

        viewer.assign("LISTVIEW_MASSACTIONS", linkModels.get("LISTVIEWMASSACTION"));

        viewer.assign("PAGING_MODEL", pagingModel);
        viewer.assign("PAGE_NUMBER", pageNumber);

        viewer.assign("ORDER_BY", orderBy);
        viewer.assign("SORT_ORDER", sortOrder);
        viewer.assign("NEXT_SORT_ORDER", nextSortOrder);
        viewer.assign("SORT_IMAGE", sortImage);
        viewer.assign("COLUMN_NAME", orderBy);

        viewer.assign("LISTVIEW_ENTRIES_COUNT", noOfEntries);
        viewer.assign("LISTVIEW_HEADERS", listViewHeaders);
        viewer.assign("LISTVIEW_ENTRIES", listViewEntries);

        if (getAppContextBean(PerformancePrefs.class).LISTVIEW_COMPUTE_PAGE_COUNT) {
            int totalCount = listViewModel.getListViewCount();
            int pageLimit = pagingModel.getPageLimit();
            int pageCount = (int) Math.ceil(1.0 * totalCount / pageLimit);

            if (pageCount == 0) {
                pageCount = 1;
            }
            viewer.assign("PAGE_COUNT", pageCount);
            viewer.assign("LISTVIEW_COUNT", totalCount);
        }
        viewer.assign("LIST_VIEW_MODEL", listViewModel);
        viewer.assign("GROUPS_IDS", RapidUtilHelper.getGroupsIdsForUsers(currentUser.getId()));
        viewer.assign("IS_MODULE_EDITABLE", listViewModel.getModule().isPermitted("EditView"));
        viewer.assign("IS_MODULE_DELETABLE", listViewModel.getModule().isPermitted("Delete"));
        viewer.assign("SEARCH_DETAILS", searchParmams);
    }

    /**
     * Function returns the number of records for the current filter
     *
     * @param request HttpServletRequest
     */
    public Map<String, Object> getRecordsCount(HttpServletRequest request) {
        String moduleName = getModule(request);
        String cvId = request.getParameter("viewname");
        Integer count = this.getListViewCount(request);

        Map<String, Object> result = new HashMap<>(3);
        result.put("module", moduleName);
        result.put("viewname", cvId);
        result.put("count", count);

        return result;
    }

    /**
     * Function to get listView count
     *
     * @param request HttpServletRequest
     */
    private Integer getListViewCount(HttpServletRequest request) {
        String moduleName = getModule(request);
        String cvId = request.getParameter("viewname");
        if (EasyStringUtil.isBlank(cvId)) {
            cvId = "0";
        }

        String searchKey = request.getParameter("search_key");
        String searchValue = request.getParameter("search_value");

        RapidListViewModel listViewModel = getAppContextBean(RapidListViewModelProvider.class).getInstance(moduleName, cvId);

        String[] searchParams = request.getParameterValues("search_params");
        listViewModel.set("search_params", this.transferListSearchParamsToFilterCondition(searchParams, listViewModel.getModule()));

        listViewModel.set("search_key", searchKey);
        listViewModel.set("search_value", searchValue);
        listViewModel.set("operator", request.getParameter("operator"));

        return listViewModel.getListViewCount();
    }


    /**
     * Function to get the page count for list
     *
     * @return total number of pages
     */
    public Map<String, Object> getPageCount(HttpServletRequest request) {
        int listViewCount = this.getListViewCount(request);
        RapidPagingModel pagingModel = new RapidPagingModel();
        int pageLimit = pagingModel.getPageLimit();
        int pageCount = (int) Math.ceil(1.0 * listViewCount / pageLimit);

        if (pageCount == 0) {
            pageCount = 1;
        }
        Map<String, Object> result = new HashMap<>(2);
        result.put("page", pageCount);
        result.put("numberOfRecords", listViewCount);
        return result;
    }


    public List<Map<String, Object>> transferListSearchParamsToFilterCondition(String[] listSearchParams,
                                                                               RapidModuleModel moduleModel) {

//        return Vtiger_Util_Helper::transferListSearchParamsToFilterCondition(listSearchParams, moduleModel);
        return new ArrayList<>(0);
    }
}
